package IHM;

import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.jdom.Element;

import Controle.Controleur;
import Metier.Page;
import Metier.Paragraphe;
import Metier.Projet;

/**
 * Classe de gestion des elements de l'ihm
 * @author Aubry Thomas
 * @author Bouchet Sylvain
 * @author Fauvel Alexis
 * @author Lessieur Jocelyn
 * @author Mathias Bastien 
 * @author Teuf Antoine
 * @version 1.0
 */
public class IHM extends JFrame{
	
	/**
	 * contient l'instance de la MenuBar de l'application
	 * @see IHM#getMB()
	 */
	private MenuBar mb;
	
	/**
	 * Contient l'instance de la ZoneTexte de l'application
	 * @see IHM#getZoneTexte()
	 */
	private ZoneTexte text;
	
	/**
	 * Contient l'instance de la ToolBar de l'application
	 * @see IHM#getToolBar()
	 * @see IHM#setToolBar()
	 */
	private ToolBar toolbar;
	
	/**
	 * Contient l'instance de la ToolBarModif de l'application
	 * @see IHM#getToolBarModif()
	 * @see IHM#setToolBarModif(Element)
	 */
	private ToolBarModif tbmodif;
	
	/**
	 * Contient l'instance de l'Arborescence de l'application
	 * @see IHM#creerArbre()
	 * @see IHM#getArborescence()
	 * @see IHM#majArbre()
	 */
	private Arborescence arb;
	
	/**
	 * Contient l'instance de la Visu de l'application
	 * @see IHM#changerVisu(String, String)
	 * @see IHM#getVisu()
	 * @see IHM#majVisu()
	 */
	private Visu visu;
	
	/**
	 * Contient l'instance du Controleur de l'application
	 * @see IHM#getControleur()
	 */
	private Controleur cont;
	
	/**
	 * Panel permetant l'affichage sur l'ihm de l'arborescence et du panel d'ajout de texte
	 */
	private JPanel pArbre,panelAjoutTexte;
	
	/**
	 * Label afficher en bas à droite du logiciel permetant l'affichage d'informations diverses
	 * @see IHM#setInfo(String)
	 */
	private JLabel info;
	
	
	/**
	 * Constructeur de la classe IHM
	 * @param controleur	controleur de l'application
	 */
	public IHM(Controleur controleur) {		
		cont = controleur;
		setTitle("Generateur Site Web");
		setLocationRelativeTo(null);
		setLayout(new BorderLayout());
		setSize(1000, 700);

		// Ouvre en plein ecran
		setDefaultLookAndFeelDecorated(false);
		setExtendedState(JFrame.MAXIMIZED_BOTH);

		panelAjoutTexte = new JPanel();
		panelAjoutTexte.setLayout(new BorderLayout());
		panelAjoutTexte.setSize(getWidth(), 200);

		text = new ZoneTexte(this);
		toolbar = new ToolBar(text, this);
		tbmodif = new ToolBarModif(this,text);

		panelAjoutTexte.add(text, BorderLayout.CENTER);
		
		info = new JLabel("",JLabel.RIGHT);
		panelAjoutTexte.add(info, BorderLayout.SOUTH);
		
		setToolBar();//mise en place de la toolbar de base
		
		add(panelAjoutTexte, BorderLayout.SOUTH);

		mb = new MenuBar(this);

		pArbre = new JPanel();
		pArbre.setLayout(new BorderLayout());
		arb = creerArbre();
		arb.setAutoscrolls(true);
		pArbre.add(arb);
		pArbre.setAutoscrolls(true);
		add(pArbre, BorderLayout.WEST);

		// visu contient les éléments qui constitue la page
		visu = new Visu(this);
		visu.setPage(null);
		
		// On met visu dans un scrollpane pour pouvoir descendre le panel si
		// celui ci est plus grand que l'espace aloué
		JScrollPane sp = new JScrollPane(visu);
		sp.getVerticalScrollBar().setUnitIncrement(10);// augmente la vitesse de
		// défilement de la
		// scrollbar verticale

		add(sp);
		
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		//Utilisé pour l'appel de la sauvegarde à la fermeture de la fenetre
		addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
            	
            	if(cont.verifChangement()) {
	            	int res = JOptionPane.showConfirmDialog(null, "Souhaitez-vous enregistrer les projets modifiés ? ");
	            	
	            	switch(res){
	            	case JOptionPane.YES_OPTION:
	            		cont.sauvegarde();
	            	case JOptionPane.NO_OPTION:
	            		System.exit(0);
	            	}
            	} else
            		System.exit(0);
            }
        });

		setVisible(true);
	}

	/**
	 * Permet de recuperer la bare de menu
	 * @return	la MenuBar
	 */
	public MenuBar getMB(){
		return mb;
	}
	
	/**
	 * Permet de savoir si une modification a été effectué 
	 * @return	vrai(true) s'il y a eu modification sinon faux(false)
	 */
	public boolean getModif(){
		for(int i=0; i<panelAjoutTexte.getComponents().length;i++){
			if(panelAjoutTexte.getComponents()[i]==tbmodif)
				return true;
		}
		return false;
	}
	
	/**
	 * Permet de recuperer la toolBar
	 * @return	la ToolBar
	 */
	public ToolBar getToolBar(){
		return toolbar;
	}
	
	/**
	 * Permet de recuperer la tool barre modifier
	 * @return	ToolBarModif
	 */
	public ToolBarModif getToolBarModif(){
		return tbmodif;
	}
	
	/**
	 * Permet de generer l'arborescence 
	 * @return	l'arborescence generer
	 */
	private Arborescence creerArbre () {
		Arborescence arbo = new Arborescence(this);

		for (Projet projet : cont.getProjets()) {
			arbo.ajouterFils(projet.getNom());
			for (Page page : projet.getPages()) {
				arbo.ajouterFils(page.getNomProjet(), page.getTitrePage());
				/** Bug probable a cause des pages qui sont associés a un projet et avc le changement de nom les pages se retrouvent sans projet **/
			}
		}

		return arbo;
	}

	/**
	 * Permet d'effectuer la mise à jour de la visu
	 */
	public void majVisu() {
		visu.maj();
	}
	
	/**
	 * Permet de recuperer la visu
	 * @return	La visu
	 */
	public Visu getVisu(){
		return visu;
	}
	
	/**
	 * Permet la mise a jour de l'arborescence
	 */
	public void majArbre()
	{
		pArbre.removeAll();
		arb = creerArbre();
		pArbre.add(arb);
		pArbre.revalidate();
		pArbre.repaint();
		arb.expandRow(cont.getNumProjetEnCours()+1);
		if(cont.getProjetEnCours()!=null)
			visu.setPage(cont.getProjetEnCours().getPageEnCours());
		majVisu();
	}

	/**
	 * Permet de recuperer la zone de texte
	 * @return	la ZoneTexte
	 */
	public ZoneTexte getZoneTexte(){
		return text;
	}

	/**
	 * Permet de recuperer le controleur
	 * @return une instance de Controleur, le controleur de l'application
	 */
	public Controleur getControleur() {
		return cont;
	}
	
	/**
	 * Permet de recuperer l'arborescence
	 * @return	une instance d'arborescence, l'arborescence de l'application
	 */
	public Arborescence getArborescence(){
		return arb;
	}

	/**
	 * Permet de changer la visu selon le projet
	 * @param sProjet	projet selectionné
	 * @param sPage		page selectionnée
	 */
	public void changerVisu(String sProjet, String sPage) {
		Projet projet = cont.getProjetByNom(sProjet);
		cont.setProjetEnCours(projet);
		Page page = projet.getPageByNom(sPage);
		visu.setPage(page);
		projet.setPageEnCours(page);
		visu.maj();
		toolbar.majThemeActuel();
	}
	
	/**
	 * Permet de mettre en place la toolbar de modification
	 * @param e	element a modifier (paragraphe)
	 */
	public void setToolBarModif(Element e){
		//String contenu="";
		
		tbmodif.setElement(e);								//transmet le paragraphe a la toolbar
		panelAjoutTexte.remove(toolbar);					//supprime la toolbar de base si présente
		panelAjoutTexte.add(tbmodif, BorderLayout.NORTH);	//ajoute la toolbar de modification
		Paragraphe p=(Paragraphe)e;
		text.getJTextPane().setStyledDocument(SerialClone.clone(p.getStyleDoc()));
		panelAjoutTexte.revalidate(); 	//actualise
		panelAjoutTexte.repaint();	  	//le panel
		toolbar.activerBtnParagraphe(true);
	}
	
	/**
	 * Permet de mettre la toolbar de base en place
	 */
	public void setToolBar(){
		panelAjoutTexte.remove(tbmodif);					//retire la toolbar de modification si présente
		panelAjoutTexte.add(toolbar, BorderLayout.NORTH);	//ajoute la toolbar de base
		panelAjoutTexte.repaint(); 							//actualise le panel
		toolbar.remiseZero();
	}
	
	/**
	 * permet de modifier l'information afficher en bas
	 * @param text	information à mettre
	 */
	public void setInfo(String text) {
		info.setText(text+" ");
	}
}